/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.aspas.util;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

/**
 *
 * @author legolas
 */
public abstract class AbstractDAO {

    protected EntityManagerFactory emf;
    protected EntityManager em;
    protected UserTransaction utx;
    private DatabaseManager databaseManager;

    public AbstractDAO() {
        emf = databaseManager.getSingleton().getEntityManagerFactory();
    }

    public UserTransaction getUserTransaction() {
        utx = databaseManager.getUserTransaction();
        return utx;
    }

    public EntityManager getEm() {
        return em;
    }

    public void setEm(EntityManager em) {
        this.em = em;
    }

    public EntityManagerFactory getEmf() {
        return emf;
    }

    public void setEmf(EntityManagerFactory emf) {
        this.emf = emf;
    }
  
    public void insert(Object o) {
        em = emf.createEntityManager();
        utx = DatabaseManager.getSingleton().getUserTransaction();
        try {
            utx.begin();
            em.joinTransaction();
            em.persist(o);
            utx.commit();
        } catch (RollbackException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicMixedException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicRollbackException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalStateException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotSupportedException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            em.close();
        }
    }

    public void update(Object o) {
        em = emf.createEntityManager();
        utx = DatabaseManager.getSingleton().getUserTransaction();
        try {
            utx.begin();
            em.joinTransaction();
            em.merge(o);
            utx.commit();
        } catch (RollbackException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicMixedException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicRollbackException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalStateException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotSupportedException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            em.close();
        }
    }

    public void delete(Object id, Class classe) {
        em = emf.createEntityManager();
        utx = DatabaseManager.getSingleton().getUserTransaction();
        try {
            utx.begin();
            em.joinTransaction();
            Object o = em.find(classe, id);
            em.remove(o);
            utx.commit();
        } catch (RollbackException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicMixedException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicRollbackException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalStateException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotSupportedException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            em.close();
        }
    }

    public void deleteDinamic(String classe, String params) {
        em = emf.createEntityManager();
        utx = DatabaseManager.getSingleton().getUserTransaction();
        try {
            utx.begin();
            em.joinTransaction();
            String hql = "DELETE FROM "+classe+" " +params;

        Query query = em.createQuery(hql);
        int row = query.executeUpdate();

            utx.commit();
        } catch (RollbackException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicMixedException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (HeuristicRollbackException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalStateException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NotSupportedException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SystemException ex) {
            Logger.getLogger(AbstractDAO.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            em.close();
        }
    }

    public Object findByPk(Class classe, Integer id) {
        em = emf.createEntityManager();
        Object o = em.find(classe, id);
        em.close();
        return o;
    }

    public Object findByPk(Class classe, Object id) {
        em = emf.createEntityManager();
        Object o = em.find(classe, id);
        em.close();
        return o;
    }

    public List findAllClass(String classe) {
        em = emf.createEntityManager();
        List lista = em.createQuery("SELECT object(o) FROM "+classe+" as o").getResultList();
        em.close();
        return lista;
    }

}
